package gui;

import java.awt.Dimension;

import gui.nodes.AbstractLeaf;
import gui.nodes.AbstractNode;
import gui.nodes.EnseignantRoot;
import gui.nodes.FormationRoot;
import gui.nodes.SalleRoot;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;

public class TreeController implements TreeSelectionListener,
		TreeWillExpandListener {

	
	private static final TreeController instance = new TreeController();
	
	private JTree tree;
	private DefaultMutableTreeNode root;
	private TreePath previousSelectedPath;

	private AbstractPopupController popupController = new AbstractPopupController() {
		public JPopupMenu makePopup(int x, int y) {
			TreePath selPath = tree.getPathForLocation(x, y);

			if (selPath != null) {
				// tree.setSelectionPath(selPath);

				DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath
						.getLastPathComponent();
				return ((AbstractLeaf) node).makePopup();
			} else {
				return null; /*
							 * L'utilisateur a cliqué dans le vide, ne rien
							 * afficher
							 */
			}
		}
	};

	private TreeController() {

		root = new DefaultMutableTreeNode("root", true);

		root.add(new FormationRoot());
		root.add(new EnseignantRoot());
		root.add(new SalleRoot());

		tree = new JTree(root);
		tree.addMouseListener(popupController);
		tree.addTreeSelectionListener(this);
		tree.addTreeWillExpandListener(this);

		tree.setRootVisible(false);
	}

	public JTree getTree() {
		return tree;
	}

	public void valueChanged(TreeSelectionEvent e) {
		int n = JOptionPane.YES_OPTION;

		if (e.isAddedPath() // Un nouvel élément a été sélectionné (le listener
							// répond aussi à la désélection...)
				&& (tree.getSelectionPath() != previousSelectedPath) // Il ne
																		// s'agit
																		// pas
																		// de
																		// l'annulation
																		// d'une
																		// action
		) {

			if (MainController.getInstance().getCurrentViewPane()
					.hasBeenModified()) {
				n = JOptionPane
						.showConfirmDialog(
								MainController.getInstance().getFrame(),
								"La mise à jour de l'affichage de la fenêtre annule les données\nen cours de saisie. Souhaitez-vous poursuivre ?",
								"Données modifiées", JOptionPane.YES_NO_OPTION,
								JOptionPane.QUESTION_MESSAGE);
			}

			if (n == JOptionPane.YES_OPTION) {

				/* L'utilisateur a sélectionné un nouvel élément */
				AbstractLeaf selectedNode = (AbstractLeaf) tree
						.getLastSelectedPathComponent();

				/* Change la vue */
				selectedNode.loadPrimaryViewPane();
				previousSelectedPath = tree.getSelectionPath();
			} else {
				/* Resélectionner l'élément actuel dans l'arbre */
				if (previousSelectedPath != null) {
					tree.setSelectionPath(previousSelectedPath);
				}
			}
		}

	}

	public void treeWillCollapse(TreeExpansionEvent event)
			throws ExpandVetoException {
		// TODO Auto-generated method stub

	}

	public void treeWillExpand(TreeExpansionEvent event)
			throws ExpandVetoException {
		AbstractNode selectedNode = (AbstractNode) event.getPath()
				.getLastPathComponent();
		selectedNode.expandHook();
	}

	public void refresh(TreeNode modifiedNode) {
		((DefaultTreeModel) tree.getModel()).nodeStructureChanged(modifiedNode); /*
														 * Merci Sun pour cette
														 * magnifique
														 * démonstration de lq
														 * simplicité de Java :-{
														 * C'est tout à fait
														 * normal qu'un arbre
														 * n'ait pas de méthode
														 * pour se rafraîchir, ça
														 * serait beaucoup trop
														 * simple !
														 */
	}

	public static TreeController getInstance() {
		return instance;
	}
}
